package com.qkun.library.widget;

import android.content.Context;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View;
import android.widget.EditText;
import android.widget.NumberPicker;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.FloatRange;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Px;
import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;

import com.qkun.library.R;
import com.qkun.library.utils.MyLog;
import com.qkun.library.utils.Utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author qinkun
 * @date 6/1 0001 22:10
 * @description TODO: 通过wrap适配自定义view以及各种style
 */
public class NumberPickerDialog {

    private final Context mContext;
    @NonNull
    private final BottomDialog mBottomDialog;
    private TextView mAlertTile;
    private NumberPicker mNumberPicker;

    public static NumberPickerDialog make(@NonNull Context context) {
        return new NumberPickerDialog(context);
    }

    private NumberPickerDialog(@NonNull Context context) {
        mContext = context;
        mBottomDialog = BottomDialog.make(context).setCustomView(R.layout.layout_select_number);
        init();
    }

    private void init() {
        View contentView = mBottomDialog.getContentView();
        mAlertTile = contentView.findViewById(R.id.alert_title);
        mNumberPicker = contentView.findViewById(R.id.number_picker);
    }

    /**
     * 设置滑动监听
     *
     * @param onValueChangedListener
     * @return
     */
    public NumberPickerDialog setOnValueChangedListener(final OnValueChangedListener onValueChangedListener) {
        mNumberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            //当NumberPicker的值发生改变时，将会触发该方法
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                if (Utils.nonNull(onValueChangedListener)) {
                    onValueChangedListener.onValueChange(NumberPickerDialog.this, picker, oldVal, newVal);
                }
            }
        });
        return this;
    }

    public NumberPickerDialog setFormatter(NumberPicker.Formatter formatter) {
        mNumberPicker.setFormatter(formatter);
        return this;
    }

    /**
     * 设置滚动监听
     * SCROLL_STATE_IDLE：不滑动
     * SCROLL_STATE_TOUCH_SCROLL：滑动中
     * SCROLL_STATE_FLING：手离开之后仍在滑动
     *
     * @param onScrollListener
     * @return
     */
    public NumberPickerDialog setOnScrollListener(NumberPicker.OnScrollListener onScrollListener) {
        mNumberPicker.setOnScrollListener(onScrollListener);
        return this;
    }

    public NumberPickerDialog setAlertTitle(CharSequence alertTitle) {
        mAlertTile.setText(alertTitle);
        return this;
    }

    public NumberPickerDialog setAlertTitle(@StringRes int resId) {
        mAlertTile.setText(resId);
        return this;
    }

    /**
     * 设置最大值
     *
     * @param maxValue
     * @return
     */
    public NumberPickerDialog setMaxValue(int maxValue) {
        mNumberPicker.setMaxValue(maxValue);
        return this;
    }

    /**
     * 设置最小值
     *
     * @param minValue
     * @return
     */
    public NumberPickerDialog setMinValue(int minValue) {
        mNumberPicker.setMinValue(minValue);
        return this;
    }

    /**
     * 设置当前值
     *
     * @param value
     * @return
     */
    public NumberPickerDialog setValue(int value) {
        mNumberPicker.setValue(value);
        return this;
    }

    /**
     * 关闭编辑模式
     *
     * @return
     */
    public NumberPickerDialog blockEdit() {
        mNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
        return this;
    }

    /**
     * 是否循环显示，默认为true，即循环显示
     *
     * @param wrapSelectorWheel
     * @return
     */
    public NumberPickerDialog setWrapSelectorWheel(boolean wrapSelectorWheel) {
        mNumberPicker.setWrapSelectorWheel(wrapSelectorWheel);
        return this;
    }

    /**
     * 设置显示的文本
     *
     * @param displayedValues
     * @return
     */
    public NumberPickerDialog setDisplayedValues(String[] displayedValues) {
        mNumberPicker.setDisplayedValues(displayedValues);
        return this;
    }


    /**
     * 设置分割线，也可以直接用{@link ColorDrawable}
     *
     * @param drawable
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public NumberPickerDialog setDividerDrawable(Drawable drawable) {
        try {
            Field field = NumberPicker.class.getDeclaredField("mSelectionDivider");
            if (Utils.nonNull(field)) {
                field.setAccessible(true);
                field.set(mNumberPicker, drawable);
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            MyLog.e(e);
        }
        return this;
    }

    /**
     * 设置分割线的粗细
     *
     * @param height
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public NumberPickerDialog setNumberPickerDivider(@IntRange(from = 0) @Px int height) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            mNumberPicker.setSelectionDividerHeight(height);
        } else {
            try {
                Field field = NumberPicker.class.getDeclaredField("mSelectionDividerHeight");
                if (Utils.nonNull(field)) {
                    field.setAccessible(true);
                    field.set(mNumberPicker, height);
                }
            } catch (NoSuchFieldException | IllegalAccessException e) {
                MyLog.e(e);
            }
        }
        return this;
    }

    /**
     * 设置数字文本颜色
     *
     * @param color
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public NumberPickerDialog setNumberTextColor(@ColorInt int color) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            mNumberPicker.setTextColor(color);
        } else {
            try {
                Field field = NumberPicker.class.getDeclaredField("mSelectorWheelPaint");
                if (Utils.nonNull(field)) {
                    field.setAccessible(true);
                    Method setColor = Paint.class.getMethod("setColor", int.class);
                    if (Utils.nonNull(setColor)) {
                        setColor.invoke(field.get(mNumberPicker), color);
                    }
                }
            } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                MyLog.e(e);
            }

            try {
                Field field = NumberPicker.class.getDeclaredField("mInputText");
                if (Utils.nonNull(field)) {
                    field.setAccessible(true);
                    Method setTextColor = EditText.class.getMethod("setTextColor", int.class);
                    if (Utils.nonNull(setTextColor)) {
                        setTextColor.invoke(field.get(mNumberPicker), color);
                    }
                }
            } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                MyLog.e(e);
            }
        }
        return this;
    }

    /**
     * 设置数字文本大小
     *
     * @param size
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public NumberPickerDialog setNumberTextSize(@FloatRange(from = 0.0, fromInclusive = false) float size) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            mNumberPicker.setTextSize(size);
        } else {
            try {
                Field field = NumberPicker.class.getDeclaredField("mSelectorWheelPaint");
                if (Utils.nonNull(field)) {
                    field.setAccessible(true);
                    Method setTextSize = Paint.class.getMethod("setTextSize", float.class);
                    if (Utils.nonNull(setTextSize)) {
                        setTextSize.invoke(field.get(mNumberPicker), size);
                    }
                }
            } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                MyLog.e(e);
            }

            try {
                Field field = NumberPicker.class.getDeclaredField("mInputText");
                if (Utils.nonNull(field)) {
                    field.setAccessible(true);
                    Method setTextSize = EditText.class.getMethod("setTextSize", float.class);
                    if (Utils.nonNull(setTextSize)) {
                        setTextSize.invoke(field.get(mNumberPicker), size);
                    }
                }
            } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                MyLog.e(e);
            }
        }
        return this;
    }

    public NumberPickerDialog addButton(@NonNull CharSequence text, @ColorInt int textColor, final OnDialogClickListener onDialogClickListener) {
        mBottomDialog.addButton(text, textColor, new BottomDialog.OnDialogClickListener() {
            @Override
            public void onClick(BottomDialog dialog, int which) {
                if (Utils.nonNull(onDialogClickListener)) {
                    onDialogClickListener.onClick(NumberPickerDialog.this, which);
                }
            }
        });
        return this;
    }

    public NumberPickerDialog addButton(@StringRes int textResId, @ColorInt int textColor, OnDialogClickListener onDialogClickListener) {
        return addButton(mContext.getResources().getString(textResId), textColor, onDialogClickListener);
    }

    public NumberPickerDialog addButton(@NonNull CharSequence text, final OnDialogClickListener onDialogClickListener) {
        return addButton(text, ContextCompat.getColor(mContext, R.color.colorPrimary), onDialogClickListener);
    }

    public NumberPickerDialog addButton(@StringRes int textResId, OnDialogClickListener onDialogClickListener) {
        return addButton(mContext.getResources().getString(textResId), onDialogClickListener);
    }

    public NumberPickerDialog addDismissButton(@NonNull CharSequence text, @ColorInt int textColor, final OnDialogClickListener onDialogClickListener) {
        mBottomDialog.addDismissButton(text, textColor, new BottomDialog.OnDialogClickListener() {
            @Override
            public void onClick(BottomDialog dialog, int which) {
                if (Utils.nonNull(onDialogClickListener)) {
                    onDialogClickListener.onClick(NumberPickerDialog.this, which);
                }
            }
        });
        return this;
    }

    public NumberPickerDialog addDismissButton(@StringRes int textResId, @ColorInt int textColor, OnDialogClickListener onDialogClickListener) {
        return addDismissButton(mContext.getResources().getString(textResId), textColor, onDialogClickListener);
    }

    public NumberPickerDialog addDismissButton(@NonNull CharSequence text, OnDialogClickListener onDialogClickListener) {
        return addDismissButton(text, ContextCompat.getColor(mContext, R.color.colorGray6), onDialogClickListener);
    }

    public NumberPickerDialog addDismissButton(@StringRes int textResId, OnDialogClickListener onDialogClickListener) {
        return addDismissButton(mContext.getResources().getString(textResId), onDialogClickListener);
    }

    public NumberPickerDialog addSureButton(@ColorInt int textColor, OnDialogClickListener onDialogClickListener) {
        return addButton(R.string.sure, textColor, onDialogClickListener);
    }

    public NumberPickerDialog addSureButton(OnDialogClickListener onDialogClickListener) {
        return addSureButton(ContextCompat.getColor(mContext, R.color.colorPrimary), onDialogClickListener);
    }

    public NumberPickerDialog addSureDismissButton(@ColorInt int textColor, OnDialogClickListener onDialogClickListener) {
        return addDismissButton(R.string.sure, textColor, onDialogClickListener);
    }

    public NumberPickerDialog addSureDismissButton(OnDialogClickListener onDialogClickListener) {
        return addSureDismissButton(ContextCompat.getColor(mContext, R.color.colorPrimary), onDialogClickListener);
    }

    public NumberPickerDialog clearAllButton() {
        mBottomDialog.clearAllButton();
        return this;
    }

    public NumberPickerDialog canCancel(boolean cancelable) {
        mBottomDialog.canCancel(cancelable);
        return this;
    }

    public NumberPickerDialog setCancelListener(final OnCancelListener onCancelListener) {
        mBottomDialog.setCancelListener(new BottomDialog.OnCancelListener() {
            @Override
            public void onCancel(BottomDialog dialog) {
                if (Utils.nonNull(onCancelListener)) {
                    onCancelListener.onCancel(NumberPickerDialog.this);
                }
            }
        });
        return this;
    }

    public boolean isShowing() {
        return mBottomDialog.isShowing();
    }

    public BottomDialog getDialog() {
        return mBottomDialog;
    }

    public int getValue() {
        return mNumberPicker.getValue();
    }

    public void dismiss() {
        mBottomDialog.dismiss();
    }

    public NumberPickerDialog show() {
        mBottomDialog.show();
        return this;
    }

    public interface OnCancelListener {
        void onCancel(NumberPickerDialog dialog);
    }

    public interface OnValueChangedListener {
        void onValueChange(NumberPickerDialog dialog, NumberPicker picker, int oldVal, int newVal);
    }

    public interface OnDialogClickListener {
        /**
         * @param dialog
         * @param which  对应添加的 Button 的位置，从 0 开始
         */
        void onClick(NumberPickerDialog dialog, int which);
    }
}
